package com.chenxin.wms.process.outbound.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chenxin.common.annotation.WmsLogs;
import com.chenxin.common.constant.WmsConstants;
import com.chenxin.common.core.domain.ProcResult;
import com.chenxin.common.enums.WmsTaskSubType;
import com.chenxin.common.enums.WmsTaskType;
import com.chenxin.common.enums.wms.ObDetailStatus;
import com.chenxin.common.enums.wms.StockQuality;
import com.chenxin.common.enums.wms.StockStatus;
import com.chenxin.common.exception.wms.WmsException;
import com.chenxin.common.utils.StringUtils;
import com.chenxin.wms.domain.ObDetailEntity;
import com.chenxin.wms.domain.StockEntity;
import com.chenxin.wms.domain.TaskEntity;
import com.chenxin.wms.domain.WcsTaskEntity;
import com.chenxin.wms.mapper.ObDetailMapper;
import com.chenxin.wms.mapper.StockMapper;
import com.chenxin.wms.mapper.TaskMapper;
import com.chenxin.wms.process.outbound.IProcObMasterStatusUpdate;
import com.chenxin.wms.process.outbound.IProcStockPrepareByDetail;
import com.chenxin.wms.process.task.ITaskProcess;
import com.chenxin.wms.process.task.IWcsTaskProcess;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
public class ProcStockPrepareByDetail implements IProcStockPrepareByDetail {
    @Autowired
    private ObDetailMapper obDetailMapper;
    @Autowired
    private StockMapper stockMapper;
    @Autowired
    private TaskMapper taskMapper;
    @Autowired
    private IWcsTaskProcess wcsTaskProcess;
    @Autowired
    private IProcObMasterStatusUpdate procObMasterStatusUpdate;

    @Override
    @Transactional
    @WmsLogs(name = "出库明细自动备货")
    public ProcResult call(Long obDetailId, Long creator) {
        // 根据明细ID获取所需信息（明细、主单、物料等）
        if (StringUtils.isNull(obDetailId)) {
            return ProcResult.error("prepare_err001", "明细ID不能为空。");
        }
        // 通过ID获取对应详情
        ObDetailEntity obDetail = obDetailMapper.selectById(obDetailId);
        if (obDetail == null) {
            return ProcResult.error("prepare_err002", "明细【" + obDetailId + "】不存在。");
        }
        // 检查单据状态（初始与备货中单据可继续备货）
        int obDetailStatus = obDetail.getObDetailStatus();
        if (obDetailStatus > 1) {
            return ProcResult.error("prepare_err003", "明细【" + obDetailId + "】当前状态【" + obDetailStatus + "】无需备货。");
        }
        Long obMasterId = obDetail.getObMasterId();
        // 计算可备货数量
        String spuNo = obDetail.getSpuNo();
        // 循环分配库存的绑定总量
        BigDecimal hasBindQty = BigDecimal.ZERO;
        BigDecimal planQty = obDetail.getObPlanQty();
        BigDecimal bindQty = obDetail.getObBindQty();
        BigDecimal reqQty = planQty.subtract(bindQty);
        Date workDate = new Date();
        if (reqQty.compareTo(BigDecimal.ZERO) <= 0) {
            return ProcResult.error("prepare_err004", "明细【" + obDetailId + "】已备货完成!无需再次备货。");
        }
        // 统计目标物料可用库存
        QueryWrapper<StockEntity> usableQW = new QueryWrapper<>();
        usableQW.eq("spu_no", spuNo)
                .eq("stock_status", StockStatus.USABLE.getCode())
                .eq("lock_status", 0)
                .eq("quality_status", StockQuality.QB.getCode());
        List<StockEntity> usableStocks = stockMapper.selectList(usableQW);
        if (usableStocks == null || usableStocks.size() == 0) {
            return ProcResult.error("prepare_err005", "明细【" + obDetailId + "】所需物料【" + spuNo + "】当前无可用库存。");
        }
        // 循环匹配库存并处理（考虑短配与超配的情况）
        for (StockEntity stock : usableStocks) {
            // 整条库存全部使用（暂定）
            BigDecimal remainQty = stock.getStockQty().subtract(stock.getLockedQty());
            // 锁定库存
            stock.setStockStatus(StockStatus.ALLOCATED.getCode());
            stock.setLockedQty(stock.getLockedQty().add(remainQty));
            stock.setUpdater(creator);
            stock.setUpdateDate(workDate);
            int stockRows = stockMapper.updateById(stock);
            if (stockRows == 0) {
                throw new WmsException("prepare_err006", "库存【" + stock.getStockId() + "】更新失败。");
            }
            // 累加备货数量
            hasBindQty = hasBindQty.add(remainQty);
            // 更新明细信息(累加绑定数量,记录备货信息-预留)
            obDetail.setObBindQty(obDetail.getObBindQty().add(remainQty));
            obDetail.setUpdater(creator);
            obDetail.setUpdateDate(workDate);
            int updateRows = obDetailMapper.updateById(obDetail);
            if (updateRows == 0) {
                throw new WmsException("prepare_err007", "明细【" + obDetailId + "】更新绑定数量失败。");
            }
            // 生成业务任务wms_task内容（不能存在不同业务类型的任务）
            TaskEntity taskByPrepare = new TaskEntity();
            taskByPrepare.setTaskType(WmsTaskType.SHIPMENT_OUT.getCode());
            taskByPrepare.setTaskSubType(WmsTaskSubType.PREPARE_OUT.getCode());
            taskByPrepare.setFromContNo(stock.getContNo());
            taskByPrepare.setFromPosition(stock.getLocationNo());
            // 工单发料时匹配对应库区的出库站台
            taskByPrepare.setToPosition("工单发料出库站台");
            taskByPrepare.setStationNo("作业站台");
            taskByPrepare.setCurPosition(stock.getLocationNo());
            taskByPrepare.setSpuNo(spuNo);
            taskByPrepare.setLotNo(stock.getLotNo());
            taskByPrepare.setPlanQty(remainQty);
            taskByPrepare.setActualQty(BigDecimal.ZERO);
            taskByPrepare.setMasterNo(obDetail.getObMasterNo());
            taskByPrepare.setMasterId(obMasterId);
            taskByPrepare.setDetailId(obDetailId);
            taskByPrepare.setStockId(stock.getStockId());
            taskByPrepare.setComments("自动备货成功");
            taskByPrepare.setCreator(creator);
            taskByPrepare.setCreateDate(workDate);
            // 写入任务
            taskMapper.insert(taskByPrepare);
            // 生成对应的设备搬送任务
            WcsTaskEntity wcsTask = new WcsTaskEntity();
            // 以时间戳作为requestPk
            wcsTask.setRequestPk(String.valueOf(System.currentTimeMillis()));
            wcsTask.setContNo(taskByPrepare.getFromContNo());
            wcsTask.setTrkType(WmsTaskType.SHIPMENT_OUT.getCode());
            wcsTask.setFrmPos(taskByPrepare.getFromContNo());
            wcsTask.setToPos(taskByPrepare.getToPosition());
            wcsTask.setCurPos(taskByPrepare.getFromContNo());
            wcsTask.setTrkStatus(WmsConstants.TASK_STATUS_INIT);
            wcsTask.setCreator(creator);
            wcsTask.setCreateDate(new Date());
            Long trkId = wcsTaskProcess.procWmsToWcsInsert(wcsTask);
            // 如果累加数量>=需求数量，则结束循环
            if (hasBindQty.compareTo(reqQty) >= 0) {
                break;
            }
        }
        // 根据备货数量判断一下单据状态
        if (hasBindQty.compareTo(reqQty) >= 0) {
            obDetail.setObDetailStatus(ObDetailStatus.PREPARED.getCode());
        } else {
            obDetail.setObDetailStatus(ObDetailStatus.PREPARING.getCode());
        }
        obDetailMapper.updateById(obDetail);
        // 同步主单状态
        procObMasterStatusUpdate.statusUpdateByMasterId(obMasterId, creator);
        return ProcResult.success("出库明细【" + obDetailId + "】备货成功!所属出库主单【" + obMasterId + "】");
    }
}
